package com.card.hwatt.controllers;

import java.io.File;
import java.io.FileInputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.card.hwatt.assembler.*;
import com.card.hwatt.service.*;
import com.card.hwatt.core.RequestJsonParam;
import com.card.hwatt.dto.*;

/**
 * 特殊考勤
 * @author Administrator
 *
 */
@Controller
@Scope("prototype")
@RequestMapping("/special")
public class SpecialController extends BaseController {

	@Autowired
	@Qualifier("specialService")
	private SpecialService specialService;

	@Autowired
	@Qualifier("employeeService")
	private EmployeeService employeeService;

	@Autowired
	@Qualifier("departmentService")
	private DepartmentService departmentService;

	@RequestMapping("/index")
	public String index() {
		return "special";
	}

	@RequestMapping("/save")
	public @ResponseBody
	ReturnValue save(@RequestJsonParam Special special) {
		if (special.id == null) {
			special.id = UUID.randomUUID();
		}
		special.date = new Date();
		specialService.save(SpecialAssembler.convert(special));

		ReturnValue result = new ReturnValue();
		result.message = "ok";
		result.isSucess = true;
		return result;
	}

	@RequestMapping("/saveAll")
	public @ResponseBody
	ReturnValue save(String json) {
		ObjectMapper objectMapper = new ObjectMapper();
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		objectMapper.setDateFormat(df);

		TypeReference<List<Special>> tr = new TypeReference<List<Special>>() {
		};
		try {
			List<Special> list = objectMapper.readValue(json, tr);
			for (Special special : list) {
				special.date = new Date();
				specialService.save(SpecialAssembler.convert(special));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		ReturnValue result = new ReturnValue();
		result.message = "ok";
		result.isSucess = true;
		return result;
	}

	@RequestMapping(value = "/import", method = RequestMethod.POST)
	public @ResponseBody
	PageResult<Special> importData(
			@RequestParam("filedata") MultipartFile filedata,
			HttpServletRequest request) {

		PageResult<Special> result = new PageResult<Special>();
		result.rows = new ArrayList<Special>();

		if (filedata == null || filedata.isEmpty()) {
			return result;
		}

		try {
			String realPath = request.getSession().getServletContext()
					.getRealPath("/temp");
			File dir = new File(realPath);
			if (!dir.exists()) {
				dir.mkdirs();
			}
			String path = realPath + File.separatorChar + UUID.randomUUID()
					+ ".xls";
			File file = new File(path);
			FileInputStream fis = null;
			try {
				filedata.transferTo(file);

				fis = new FileInputStream(file);
				POIFSFileSystem fs = new POIFSFileSystem(fis);
				HSSFWorkbook wb = new HSSFWorkbook(fs);
				HSSFSheet sheet = wb.getSheetAt(0);

				for (int i = 1; i < sheet.getPhysicalNumberOfRows(); i++) {

					HSSFRow row = sheet.getRow(i);
					Special special = new Special();
					result.rows.add(special);
					if (row != null) {
						HSSFCell cell = row.getCell(0);
						if (cell != null) {
							if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
								special.employeeCode = String.valueOf(Math
										.round(cell.getNumericCellValue()));
							} else {
								special.employeeCode = cell
										.getStringCellValue();
							}
						}

						cell = row.getCell(2);
						if (cell != null) {
							if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
								special.cardDate = cell.getDateCellValue();
							} else {
								String[] parsePatterns = { "yyyy/MM/dd",
										"yyyy/M/d", "yyyy/M/dd", "yyyy/MM/d",
										"yyyy-MM-dd", "yyyy-M-d", "yyyy-M-dd",
										"yyyy-MM-d", "yyyy年MM月dd日",
										"yyyy年M月d日", "yyyy年M月dd日", "yyyy年MM月d日" };
								special.cardDate = DateUtils.parseDate(
										cell.getStringCellValue(),
										parsePatterns);
							}
						}

						cell = row.getCell(3);
						if (cell != null) {
							if (cell.getCellType() != HSSFCell.CELL_TYPE_NUMERIC) {
								special.reason = cell.getStringCellValue();
							}
						}
					}
				}

			} finally {
				if (fis != null) {
					fis.close();
				}
				if (file.exists()) {
					file.delete();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		StringBuilder builder = new StringBuilder();
		List<Object> params = new ArrayList<Object>();
		for (Special special : result.rows) {
			builder.append(" or employeeCode = ? ");
			params.add(special.employeeCode);
		}
		if (builder.length() > 0) {
			List<Employee> employeeList = EmployeeAssembler
					.convert(employeeService.loadAll(new PageParam(0, 0,
							" id != id " + builder.toString(), params,
							" employeeCode asc ")).rows);
			List<Special> list = new ArrayList<Special>();

			for (Special item : result.rows) {
				for (Employee employee : employeeList) {
					if (item.employeeCode.equals(employee.employeeCode)) {
						Special special = new Special();
						special.cardDate = item.cardDate;
						special.employeeId = employee.id;
						special.employeeCode = employee.employeeCode;
						special.employeeName = employee.name;
						special.reason = item.reason;
						special.id = UUID.randomUUID();
						list.add(special);
						break;
					}
				}
			}
			result.footer = new ArrayList<Special>();
			Special footer = new Special();
			result.footer.add(footer);
			footer.employeeCode = "共计" + result.rows.size() + "条";
			footer.employeeName = "正确数据" + list.size() + "条";

			if (list.size() != result.rows.size()) {
				footer.reason = "错误数据" + (result.rows.size() - list.size())
						+ "条";
			}
			result.rows = list;
		} else {
			result.rows.clear();
		}

		result.total = result.rows.size();
		return result;
	}

	@RequestMapping("/delete")
	public @ResponseBody
	ReturnValue delete(@RequestParam UUID id) {
		specialService.delete(id);
		ReturnValue result = new ReturnValue();
		result.message = "ok";
		result.isSucess = true;
		return result;
	}

	@RequestMapping("/print")
	public @ResponseBody
	void print(HttpServletRequest request, HttpServletResponse response,
			Long id, String name, String user, String startDate, String endDate) {

		if (id == null) {
			PageResult<Special> result = new PageResult<Special>();
			result.rows = new ArrayList<Special>();
			return;
		}

		Department department = DepartmentAssembler.convert(departmentService
				.get(id));
		if (department == null) {
			return;
		}

		StringBuilder where = new StringBuilder(
				" card.employee.department.path like ? ");
		List<Object> param = new ArrayList<Object>();
		param.add("%@" + id + "@%");

		if (StringUtils.isNotEmpty(name)) {
			param.add("%" + name + "%");
			param.add("%" + name + "%");

			where.append(" and (card.employee.name like ? or card.employee.employeeCode like ? ) ");
		}

		String title = StringUtils.EMPTY;
		if (StringUtils.isNotEmpty(startDate)
				&& StringUtils.isNotEmpty(endDate)) {
			String[] parsePatterns = { "yyyy-MM-dd", "yyyy-M-dd", "yyyy-M-d" };

			try {
				Date start = DateUtils.parseDate(startDate, parsePatterns);
				Date end = DateUtils.parseDate(endDate, parsePatterns);
				Calendar calendar = Calendar.getInstance();
				calendar.setTime(end);
				calendar.add(Calendar.DATE, 1);
				end = calendar.getTime();

				param.add(new java.sql.Date(start.getTime()));
				param.add(new java.sql.Date(end.getTime()));

				where.append(" and date >= ? and date < ? ");

				calendar.setTime(start);
				title = calendar.get(Calendar.YEAR) + "年"
						+ (calendar.get(Calendar.MONTH) + 1) + "月";
			} catch (Exception e) {

			}
		}

		List<Special> list = SpecialAssembler.convert(specialService
				.loadAll(new PageParam(0, 0, where.toString(), param,
						" date desc "))).rows;

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("start", startDate);
		params.put("end", endDate);
		params.put("title", department.name + title + "员工加班及特殊考勤统计表");
		params.put("name", user == null ? StringUtils.EMPTY : "打印人：" + user);
		params.put("date",
				"打印日期：" + DateFormatUtils.format(new Date(), "yyyy-MM-dd"));
		this.print(request, response, "special", list, params);
	}

	@RequestMapping("/loadAll")
	public @ResponseBody
	PageResult<Special> loadAll(Long id, String name, String startDate,
			String endDate, int page, int rows) {

		if (id == null) {
			PageResult<Special> result = new PageResult<Special>();
			result.rows = new ArrayList<Special>();
			return result;
		}

		StringBuilder where = new StringBuilder(
				" card.employee.department.path like ? ");
		List<Object> param = new ArrayList<Object>();
		param.add("%@" + id + "@%");

		if (StringUtils.isNotEmpty(name)) {
			param.add("%" + name + "%");
			param.add("%" + name + "%");

			where.append(" and (card.employee.name like ? or card.employee.employeeCode like ? ) ");
		}

		if (StringUtils.isNotEmpty(startDate)
				&& StringUtils.isNotEmpty(endDate)) {
			String[] parsePatterns = { "yyyy-MM-dd", "yyyy-M-dd", "yyyy-M-d" };

			try {
				Date start = DateUtils.parseDate(startDate, parsePatterns);
				Date end = DateUtils.parseDate(endDate, parsePatterns);
				Calendar calendar = Calendar.getInstance();
				calendar.setTime(end);
				calendar.add(Calendar.DATE, 1);
				end = calendar.getTime();

				param.add(new java.sql.Date(start.getTime()));
				param.add(new java.sql.Date(end.getTime()));

				where.append(" and date >= ? and date < ? ");
			} catch (Exception e) {

			}
		}

		PageResult<Special> result = SpecialAssembler.convert(specialService
				.loadAll(new PageParam(rows, page, where.toString(), param,
						" date desc ")));

		return result;
	}
}
